<?php

declare(strict_types=1);

namespace App\Robot\Service;

use App\Common\Helpers\VideoHelper;
use App\Common\Robot\Gateways\Gateway;
use App\Robot\Constants\UploadFileTypeConstants;
use App\Robot\Dto\FileMessageDTO;
use App\Robot\Dto\GifMessageDTO;
use App\Robot\Dto\ImageMessageDTO;
use App\Robot\Dto\MiniProgramMessageDTO;
use App\Robot\Dto\UrlMessageDTO;
use App\Robot\Dto\VideoMessageDTO;

class MessageDataService
{
    public function getTextData($content)
    {

    }

    /**
     * 图片消息数据
     * @param Gateway $robotApiService
     * @param string $url
     * @param mixed $toId
     * @return ImageMessageDTO|array
     */

    public function getImageData(Gateway $robotApiService,string $url,mixed $toId,string $filename = ''): ImageMessageDTO|array
    {
        if(empty($filename)){
            $filename = get_remote_file_name($url);
        }
        $result = $this->uploadfile($robotApiService,$url,UploadFileTypeConstants::IMAGE,$filename);
        if(empty($result)){
            return [];
        }

        $data = (new ImageMessageDTO())
            ->setFileAesKey($result['file_aes_key'])
            ->setFileId($result['file_id'])
            ->setFileMd5($result['file_md5'])
            ->setFileSize($result['file_size'])
            ->setFileName($filename)
            ->setToId($toId);
        return $data;
    }

    /**
     * GIF消息数据
     * @param Gateway $robotApiService
     * @param string $url
     * @param mixed $toId
     * @param string $filename
     * @return GifMessageDTO|array
     */
    public function getGifData(Gateway $robotApiService,string $url,mixed $toId,string $filename = ''):GifMessageDTO|array
    {
        if(empty($filename)){
            $filename = get_remote_file_name($url);
        }
        $result = $this->uploadfile($robotApiService,$url,UploadFileTypeConstants::IMAGE,$filename);
        if(empty($result)){
            return [];
        }

        $iconUrlResult = $robotApiService->cdnToUrl($result['file_aes_key'],$result['file_id'],$result['file_md5']);
        if($iconUrlResult === false){
            return [];
        }

        $data = (new GifMessageDTO())
            ->setWxFileUrl($iconUrlResult['file_url'])
            ->setToId($toId);
        return $data;
    }

    /**
     * 小程序消息数据
     * @param Gateway $robotApiService
     * @param array $data
     * @param mixed $toId
     * @return MiniProgramMessageDTO|array
     */
    public function getCustomMiniProgramData(Gateway $robotApiService,array $data,mixed $toId): MiniProgramMessageDTO|array
    {
        $coverUrl = $data['cover_url'];
        $filename = get_remote_file_name($coverUrl);
        $result = $this->uploadfile($robotApiService,$coverUrl,UploadFileTypeConstants::IMAGE,$filename);
        if(empty($result)){
            return [];
        }

        $iconUrl = $data['icon_url'];
        $iconFilename = get_remote_file_name($coverUrl);
        $iconResult = $this->uploadfile($robotApiService,$iconUrl,UploadFileTypeConstants::IMAGE,$iconFilename);
        if(empty($iconResult)){
            return [];
        }

        $iconUrlResult = $robotApiService->cdnToUrl($iconResult['file_aes_key'],$iconResult['file_id'],$iconResult['file_md5']);
        if($iconUrlResult === false){
            return [];
        }
        $iconUrl = $iconUrlResult['file_url'];
        $appid = array_key_exists('appid', $data) ? $data['appid'] : (array_key_exists('app_id', $data) ? $data['app_id'] : '');
        if (empty($appid)) {
            return [];
        }
        $data = (new MiniProgramMessageDTO())
            ->setTitle($data['title'] ?? '')
            ->setDesc($data['desc'] ?? '')
            ->setUsername($data['username'])
            ->setPagePath($data['pagepath'] ?? '')
            ->setAppId($appid)
            ->setCoverFileAesKey($result['file_aes_key'])
            ->setCoverFileId($result['file_id'])
            ->setCoverFileSize($result['file_size'])
            ->setCoverImageMd5($result['file_md5'])
            ->setThumbUrl($iconUrl)
            ->setToId($toId);
        return $data;
    }

    /**
     * 视频消息数据
     * @param RobotApiService $robotApiService
     * @param string $videoUrl
     * @param mixed $toId
     * @return VideoMessageDTO|array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function getVideoData(Gateway $robotApiService,string $videoUrl,mixed $toId,string $filename = ''): array|VideoMessageDTO
    {
        if(empty($filename)){
            $filename = get_remote_file_name($videoUrl);
        }

        $result = $this->uploadfile($robotApiService,$videoUrl,UploadFileTypeConstants::VIDEO,$filename);
        if(empty($result)){
            return [];
        }

        $videoHelper = container()->get(VideoHelper::class);
        //视频封面
        $videoCover = $videoHelper->getVideoCover($videoUrl);
        //视频时长
        $videoDuration = $videoHelper->getVideoDuration($videoUrl);
        //封面大小
        $coverImageSize = get_image_info($videoCover)['size'] ?? 0;

        $previewImgUrl = '';
        if(str_contains($result['file_id'],'*')){
            $previewImgUrl = $videoCover;
        }

        $data = (new VideoMessageDTO())
            ->setCoverImageSize($coverImageSize)
            ->setDuration($videoDuration)
            ->setFileAesKey($result['file_aes_key'] ?? '')
            ->setFileId($result['file_id'])
            ->setFileSize($result['file_size'])
            ->setFileMd5($result['file_md5'])
            ->setFileName($filename)
            ->setPreviewImgUrl($previewImgUrl)
            ->setToId($toId);
        return $data;
    }

    public function getFileData(Gateway $robotApiService,string $url,mixed $toId,string $filename = ''): FileMessageDTO|array
    {
        if(empty($filename)){
            $filename = get_remote_file_name($url);
        }

        $result = $this->uploadfile($robotApiService,$url,UploadFileTypeConstants::FILE,$filename);
        if(empty($result)){
            return [];
        }

        $data = (new FileMessageDTO())
            ->setFileAesKey($result['file_aes_key'])
            ->setFileId($result['file_id'])
            ->setFileSize($result['file_size'])
            ->setFileName($filename)
            ->setToId($toId);
        return $data;
    }

    /**
     * 链接消息数据
     * @param array $content
     * @param mixed $toId
     * @return UrlMessageDTO
     */
    public function getUrlData(array $content,mixed $toId): UrlMessageDTO
    {
        $data = (new UrlMessageDTO())
            ->setTitle($content['title'] ?? '')
            ->setDesc($content['desc'] ?? '')
            ->setLinkUrl($content['url'])
            ->setIconUrl($content['cover'] ?? '')
            ->setToId($toId);
        return $data;
    }

    private function uploadfile(Gateway $robotApiService,string $url,int $type,string $filename = '')
    {
        $key = 'robot_file_upload_v1:'.md5($url).'_'.$type;
        $result = redis()->get($key);
        if($result){
            return $this->changeData($result);
        }
        $result = $robotApiService->cdnBigUpload($url,$filename,$type);
        if($result === false){
            return [];
        }
        $result = $this->changeData($result);
        redis()->set($key,$result,3 * 86400);
        return $result;
    }

    private function changeData(array $data): array
    {
        if(isset($data['file_aeskey'])){
            $data['file_aes_key'] = $data['file_aeskey'];
        }
        return $data;
    }
}